/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-4-23 下午10:19 Created by dwzhang
 */
package com.jade.framework.base.criterion.sql;

import com.jade.framework.base.criterion.Constants;
import com.jade.framework.base.criterion.CriterionInterpreter;
import com.jade.framework.base.criterion.expression.LikeExpression;

/**
 * 把LikeExpression转换成SQL语句。
 *
 * @author dwzhang
 * @version 1.0 13-4-23 下午10:19
 */
public class LikeInterpreter implements CriterionInterpreter<SqlContext, LikeExpression>
{
    /** 默认的转义字符串 */
    public static final String[] defaultChars = new String[]{"%", "_", "％"};

    /** 配置文件获取的key */
    public static final String ESCAPE_CHARS = "sql.escapeChars";

    /**
     * 对表达式进行解析，形成可以用于实际查询的上下文。
     *
     * @param context    解析上下文。
     * @param expression 需要解析的对象，包括表达式、Order等等。
     */
    public void interprete(SqlContext context, LikeExpression expression)
    {
        context.append(expression.getFullName());
        context.append(Constants.BLANK);
        context.append(Constants.LIKE);
        context.append(Constants.BLANK);
        context.append(Constants.INTERROGATION_POINT);
        Character escapeChar = expression.getEscapeChar();
        if (escapeChar != null) {
            context.append(" escape \'" + escapeChar + "\'");
            context.addPrepraredValue(expression.getMatchMode().toMatchString(expression.getValue().toString()));
        }
        else if (expression.isEsc()) {
            escapeChar = '^';
            Object value = expression.getValue();
            if (value instanceof String) {
                value = escapeChars((String)value, escapeChar, defaultChars);
                context.append(" escape \'" + escapeChar + "\'");
                context.addPrepraredValue(expression.getMatchMode().toMatchString((String)value));
            }
        }
    }

    /**
     * 转义特殊字符
     *
     * @param value      需要转义的字符串
     * @param chars      转义字符数字
     * @param escapeChar 转义标识符
     * @return 转义后的字符串
     */
    protected String escapeChars(String value, Character escapeChar, String... chars)
    {
        for (int i = 0; chars != null && i < chars.length; i++) {
            value = value.replaceAll(chars[i], escapeChar + chars[i]);
        }
        return value;
    }
}
